﻿#include "common/logger/logger.h"
#include <QDebug>
#include <common/codeimagegenerate/codeimageconfig.h>

IconConfig::IconConfig()
{
	m_scalePercent = 20;
	m_borderWidth = 2;
	m_isDrawRect = true;
}
IconConfig& IconConfig::setImage(const QImage& image)
{
	m_image = image;
	return *this;
}

IconConfig& IconConfig::setScalePercent(uint8_t percent)
{
	m_scalePercent = qBound(5, static_cast<int>(percent), 40);
	return *this;
}

IconConfig& IconConfig::setBorderWidth(uint8_t width)
{
	m_borderWidth = width;
	return *this;
}
IconConfig& IconConfig::setDrawRect(bool enabled)
{
	m_isDrawRect = enabled;
	return *this;
}

CodeImageConfig::CodeImageConfig()
{
	m_type = BarcodeType::QR_CODE;
	m_errorLevel = ErrorCorrectionLevel::MEDIUM;
	m_size = QSize();
	m_fgColor = Qt::black;
	m_bgColor = Qt::white;
	m_quietHeight = 0;
	m_quietWidth = 0;
	m_quietZone = true;
	m_showText = true;
}

CodeImageConfig& CodeImageConfig::setType(BarcodeType type)
{
	m_type = type;
	return *this;
}

CodeImageConfig& CodeImageConfig::setSize(const QSize& size)
{
	m_size = size;
	return *this;
}

CodeImageConfig& CodeImageConfig::setErrorCorrection(ErrorCorrectionLevel level)
{
	m_errorLevel = level;
	return *this;
}

CodeImageConfig& CodeImageConfig::setColors(const QColor& foreground, const QColor& background)
{
	m_fgColor = foreground;
	m_bgColor = background;
	return *this;
}

CodeImageConfig& CodeImageConfig::setQuietZone(bool enabled)
{
	m_quietZone = enabled;
	return *this;
}

CodeImageConfig& CodeImageConfig::setShowText(bool show)
{
	m_showText = show;
	return *this;
}
CodeImageConfig& CodeImageConfig::setQuietZoneWidth(int width)
{
	m_quietWidth = width;
	return *this;
}

BarcodeType CodeImageConfig::getType() const
{
	return m_type;
}

QSize CodeImageConfig::getSize() const
{
	return m_size;
}

ErrorCorrectionLevel CodeImageConfig::getErrorLevel() const
{
	return m_errorLevel;
}

QColor CodeImageConfig::getFgColor() const
{
	return m_fgColor;
}

QColor CodeImageConfig::getBgColor() const
{
	return m_bgColor;
}

bool CodeImageConfig::getQuietZone() const
{
	return m_quietZone;
}
int CodeImageConfig::getQuietZoneWidth() const
{
	return m_quietHeight;
}

int CodeImageConfig::getQuietZoneHeight() const
{
	return m_quietHeight;
}
bool CodeImageConfig::getShowText() const
{
	return m_showText;
}

IconConfig CodeImageConfig::getIcon() const
{
	return m_iconConfig;
}

bool CodeImageConfig::operator==(const CodeImageConfig& code_config) const
{
	return m_type == code_config.m_type &&
		   m_size == code_config.m_size &&
		   m_errorLevel == code_config.m_errorLevel &&
		   m_fgColor == code_config.m_fgColor &&
		   m_bgColor == code_config.m_bgColor &&
		   m_quietZone == code_config.m_quietZone &&
		   m_showText == code_config.m_showText &&
		   m_iconConfig.getImage() == code_config.m_iconConfig.getImage() &&
		   m_iconConfig.getScalePercent() == code_config.m_iconConfig.getScalePercent() &&
		   m_iconConfig.getBorderWidth() == code_config.m_iconConfig.getBorderWidth() &&
		   m_iconConfig.isDrawRect() == code_config.m_iconConfig.isDrawRect();
}

CodeImageConfig& CodeImageConfig::setQuietZoneHeight(int height)
{
	m_quietHeight = height;
	return *this;
}

CodeImageConfig& CodeImageConfig::setIcon(const IconConfig& icon)
{
	m_iconConfig = icon;

	//如果设置中心图标的话，要保证容错率在可控范围内，防止扫描不出来
	const uint8_t& percent = icon.getScalePercent();

	if (percent >= 5 && percent < 15)
	{
		m_errorLevel = ErrorCorrectionLevel::MEDIUM;
	}
	else if (percent >= 15 && percent < 25)
	{
		m_errorLevel = ErrorCorrectionLevel::QUARTILE;
	}
	else if (percent >= 25 && percent <= 30)
	{
		m_errorLevel = ErrorCorrectionLevel::HIGH;
	}
	else
	{
		m_iconConfig.setScalePercent(20);//视觉效果和扫描的平衡
		m_errorLevel = ErrorCorrectionLevel::HIGH;
		LOG_WARN(QString("超过图标比例最大限制30%或最小限制5%，已自动调整为20%").toStdString());
	}
	return *this;
}

QImage IconConfig::getImage() const
{
	return m_image;
}

uint8_t IconConfig::getScalePercent() const
{
	return m_scalePercent;
}

uint8_t IconConfig::getBorderWidth() const
{
	return m_borderWidth;
}
bool IconConfig::isDrawRect() const
{
	return m_isDrawRect;
}

bool IconConfig::isValid() const
{
	return !m_image.isNull();
}

CodeImageConfig CodeImageConfig::defaultQRCode()
{
	return CodeImageConfig().setType(BarcodeType::QR_CODE).setErrorCorrection(ErrorCorrectionLevel::MEDIUM).setQuietZone(true);
}
CodeImageConfig CodeImageConfig::defaultBarcode()
{
	return CodeImageConfig().setType(BarcodeType::CODE_128).setShowText(true).setQuietZone(true);
}